home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / SCLIB.ARJ / SCL1SAMP.EXE / USERFLD.C < prev    next >
Text File  |  1992-01-01  |  9KB  |  280 lines

  1. /****************************************************************************
  2.     USERFLD.C   This file shows how to create an user defined field type
  3.     to use with the Fields2 function.
  4.  
  5.     We'll create a field that displays one of several predefined strings.
  6.     The user can select one by using the UP and DOWN arrow keys or cliking
  7.     the mouse at two small arrows. To create an user defined field we need
  8.     to create the function that will handle the new field type. This
  9.     function must follow the following requirements:
  10.  
  11.     1) Handle the following messages:
  12.  
  13.         Message         Action
  14.  
  15.         RESET       -   Reset all internal variables to start-up conditions.
  16.         DRAW        -   Draw itself
  17.         ACTIVE      -   Get user input
  18.         CHECK_MOUSE -   Check if a mouse event has ocuured inside field
  19.                         area.
  20.  
  21.     2) Return the following messages:
  22.  
  23.         Message         Action
  24.  
  25.         OK          -   Action requested was succesfully performed.
  26.         EXIT_KEY    -   A key defined as an exit key was pressed.
  27.         ILLEGAL_KEY -   An unknown key was pressed.
  28.         MOUSE_EVENT -   A mouse event not related to this function has
  29.                         ocurred.
  30.         MY_MOUSE    -   A CHECK_MOUSE message is answered with this message
  31.                         if the mouse event is related to this function.
  32.                         Fields will give control to this function when a
  33.                         MY_MOUSE event is returned.
  34.  
  35.         NEW_POSITION-   the user has moved to a new position or selected
  36.                         a new element. (This one is not required but it
  37.                         is highly recomended).
  38.  
  39.     3) All local data (color, position, etc) must be stored in a structure.
  40.        A pointer to this structure will be passed as parameter whenever the
  41.        function is called. Take a look at any SCL1 dialog function for an
  42.        example. The use of a structure to hold local data makes possible
  43.        for a single LineEditor struct to handle all LineEditors fields in
  44.        a data-entry screen for example.
  45.  
  46.     4) The follwing parameters are passed each time the function is called:
  47.  
  48.         Message (int)   one of the messages described above in #1.
  49.  
  50.         st (void *)     pointer to the field related structure.
  51.  
  52.         fd3 (FData3 *)  pointer to a FData3 struct. This structure has
  53.                         the following format:
  54.  
  55.             typedef struct{
  56.                 int EventInfo;
  57.                 int (* cdecl UserField)();
  58.                 }FData3;
  59.  
  60.     5) When called the function must:
  61.  
  62.         1) service the message received
  63.         2) In case of an illegal or exit key copy the key's SCAN/ASCII code
  64.            to the EventInfo element of the FData3 struct.
  65.         3) return the correct message.
  66.  
  67.     Before calling Fields2 you must properly initialize the user defined and 
  68.     the FData3 structure. In the case of the FData3 struct only the UserField 
  69.     element needs to be initialized (points to the function that will handle
  70.     the user defined field type).
  71.  
  72. ****************************************************************************/
  73.  
  74. #include <scl1.h>
  75. #include <scl1keys.h>
  76.  
  77. /* function protoype of our new field handler */
  78.  
  79. int SelectString(int Message,void *st,FData3 *fd3);
  80.  
  81.     /* new field data */
  82.  
  83. char *MyText[]={
  84.     "111111111111111111",
  85.     "222222222222222222",
  86.     "333333333333333333",
  87.     0,
  88.     };
  89.  
  90. typedef struct{     /* our new field structure */
  91.     int Color;
  92.     int Row;
  93.     int Col;
  94.     int Position;
  95.     int Items;
  96.     int Lenght;
  97.     char **Text;
  98.     }SSData;
  99.  
  100.     /* initialize our field struct */
  101.  
  102. SSData ssd={7,7,13,0,3,0,MyText};
  103.  
  104.     /* a mouse button struct */
  105.  
  106. MBData mb={7,112,9,13,9,18,9,13,"< OK >",0,0,0,0};
  107.  
  108.     /* our FData3 struct. It is very important to initialize this struct
  109.        so that the UserField element points to the function that handles
  110.        the new field type */
  111.  
  112. FData3 ssfd3={0,SelectString};
  113.  
  114.     /* FData1 struct */
  115.  
  116. FData1 fd1[]={
  117.  
  118.     /* First field is our used defined field, the SSData pointer
  119.        is used as Structure1 element and the FData3 pointer as
  120.        Structure2 element
  121.  
  122.        We'll use SCL1's default FieldCheck function */
  123.  
  124.     USER_DEFINED,&ssd,&ssfd3,FieldCheck,
  125.     MOUSE_BUTTON,&mb,0,FieldCheck,
  126.     0};
  127.  
  128. main()
  129. {
  130. FData2 fd2;
  131.  
  132. Cls(7,CLS_ALL);                 /* Clear screen */
  133. InitMouse(IM_SHOW);             /* initialize mouse */
  134. Fields2(F_INIT,fd1,&fd2);       /* init fields */
  135. Fields2(F_DRAW,fd1,&fd2);       /* draw */
  136. Fields2(F_ACTIVE,fd1,&fd2);     /* give control */
  137. }
  138.  
  139. /* our new field type. Here we'll send received messages for processing */
  140.  
  141. int SelectString(int Message,void *st,FData3 *fd3)
  142. {
  143. SSData *ssd;
  144.  
  145. ssd=(SSData *)st;
  146.  
  147.     /* you could define messages for your field, but the value assigned
  148.       to each message must equal those assigned to regular dialog
  149.       functions. In our case we'll use LineEditor messages */
  150.  
  151. switch(Message)
  152.     {
  153.     case LE_DRAW:
  154.         DrawUF(ssd);
  155.         return(LE_OK);
  156.     case LE_ACTIVE:
  157.         return(ActiveUF(ssd,fd3));
  158.     case LE_CHECK_MOUSE:
  159.         return(CheckUFMouse(ssd,fd3));
  160.     case LE_RESET:
  161.         ssd->Position=0;        /* reset position to 0 */
  162.         return(LE_OK);
  163.     }
  164. return(LE_OK);
  165. }
  166.  
  167. /* draws our field to the screen and initializes several elements of our
  168.    struct */
  169.  
  170. int DrawUF(SSData *ssd)
  171. {
  172. int i=0,j,maxlenght=0;
  173.  
  174. while(ssd->Text[i] != 0)        /* count the number of items */
  175.     {
  176.     j=strlen(ssd->Text[i]);     /* save the largest element size */
  177.     if(j > maxlenght)
  178.         maxlenght=j;
  179.     ++i;
  180.     }
  181. ssd->Items=i;                   /* save in struct */
  182. ssd->Lenght=maxlenght;
  183.  
  184.     /* write string */
  185.  
  186. WriteScreenLen(ssd->Color,ssd->Row,ssd->Col+2,maxlenght,ssd->Text[ssd->Position]);
  187.  
  188.     /* draw up and down arrows */
  189.  
  190. WriteChar(ssd->Color,ssd->Row,ssd->Col,1,24);
  191. WriteChar(ssd->Color,ssd->Row,ssd->Col+maxlenght+3,1,25);
  192. }
  193.  
  194.     /* This functions is called when our field is active */
  195.  
  196. ActiveUF(SSData *ssd,FData3 *fd3)
  197. {
  198. unsigned int key;
  199.  
  200. SetCurPos(ssd->Row,ssd->Col+2);         /* position cursor */
  201. do
  202.     {
  203.     if(MSE_LPress)                      /* mouse event? */
  204.         {
  205.         if(CheckUFMouse(ssd)==LE_MY_MOUSE)  /* our mouse? */
  206.             {
  207.             if(MSE_LpX==ssd->Col)       /* clicked at the up arrow key */
  208.                 {
  209.                 WaitTime(25);
  210.                 goto UpKey;
  211.                 }
  212.                 
  213.                 /* clicked at the down arrow key */
  214.  
  215.             else if(MSE_LpX==ssd->Col+ssd->Lenght+3)
  216.                 {
  217.                 WaitTime(25);
  218.                 goto DownKey;
  219.                 }
  220.             }
  221.  
  222.         else
  223.  
  224.           /* clicked outside our area, return a MOUSE_EVENT message */
  225.  
  226.             return(LE_MOUSE_EVENT);
  227.         }
  228.  
  229.     if(KeyReady())      /* check keystrokes */
  230.         {
  231.         key=GetKey();
  232.         switch(key)
  233.             {
  234.             case UP:
  235. UpKey:
  236.                 if(ssd->Position > 0)
  237.                     --ssd->Position;        /* change position */
  238.                 else
  239.                     ssd->Position=ssd->Items-1;
  240.                 DrawUF(ssd);                /* update screen */
  241.                 return(LE_NEW_POSITION);
  242.             case DOWN:
  243. DownKey:
  244.                 if(ssd->Position + 1 < ssd->Items)
  245.  
  246.                     ++ssd->Position;        /* change position */
  247.                 else
  248.                     ssd->Position=0;
  249.                 DrawUF(ssd);                /* update screen */
  250.                 return(LE_NEW_POSITION);
  251.             case TAB:
  252.             case SHIFTTAB:                  /* handle exit keys */
  253.             case ESC:
  254.                 fd3->EventInfo=key;         /* save key value */
  255.                 return(LE_EXIT_KEY);
  256.             default:                        /* handle unknown keys */
  257.                 fd3->EventInfo=key;         /* save key value */
  258.                 return(LE_ILLEGAL_KEY);
  259.             }
  260.         }
  261.     }while(1);
  262. }
  263.  
  264.  
  265.     /* this function checks if the mouse has been clicked in our area */
  266.  
  267. CheckUFMouse(SSData *ssd)
  268. {
  269. if(MSE_LpY==ssd->Row && MSE_LpX >= ssd->Col && MSE_LpX <= ssd->Col+ssd->Lenght+3)
  270.  
  271.     /* return MY_MOUSE if YES */
  272.  
  273.     return(LE_MY_MOUSE);
  274.  
  275. else
  276.     return(LE_MOUSE_EVENT);
  277.  
  278. }
  279.  
  280.